/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jili.ubert;

import com.jili.ubert.code.adapter2server.ReportOrder;
import com.jili.ubert.code.client2server.AlterOrder;
import com.jili.ubert.code.client2server.CancelOrder;
import com.jili.ubert.code.client2server.NewOrder;
import com.jili.ubert.dao.NewHibernateUtil;
import com.jili.ubert.dao.sim.TradeSimOrderquene;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalTime;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.avis.client.Elvin;
import org.avis.client.Notification;

/**
 *
 * @author ChengJiLi
 */
public class ReportManager {

    private static Elvin elvin = null;
    private static final Log log = LogFactory.getLog(ReportManager.class);

    static {
        String elvinUri = System.getProperty("elvin", "elvin://localhost");
        try {
            elvin = new Elvin(elvinUri);
            log.info("启动连接avis router:" + elvinUri);
            //System.out.println("启动连接avis router:"+elvinUri);
            elvin.closeOnExit();
        } catch (Exception e) {
            log.info(e);
        }
    }

    public ReportManager(Elvin elvin) {
        this.elvin = elvin;
    }
    /*
     1.委托回报：MsgType:C1：下单回报，C2:撤单回报,C3:改价回报
     1)模拟成交：OR:订单委托回报，OS:订单成交回报；CR:撤单委托回报，CS:撤单成交回报；AR改单委托回报，AS：改单成交回报；OO：其他指令单回报
     2）内部成交：IS:内部成交回报，IC：内部撤单回报，IA: 内部改单回报；注意，内部成交不需要委托确认，直接处理结果
     3）内部移仓：PS：内部移仓成交回报
     4）状态修订：ST:状态修复回报
     2.多态处理，接收3种委托
     type:1.模拟成交，2.内部成交，3.内部移仓，4.状态修改；OrderType只在type为1的时候有效
     */

    public static void CommitReport(NewOrder order, int orderQty, int type) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        //生成回报主体
        //order复制
        reportOrder.setOrderId(order.getOrderId());
        reportOrder.setWorkingQty(orderQty);
        reportOrder.setUnWorkingQty(0);
        reportOrder.setCancelQty(0);
        reportOrder.setPrice(order.getOrderPrice());
        reportOrder.setAccountCode(order.getAccountCode());
        reportOrder.setObj(order.getObj());
        reportOrder.setMarketCode(order.getMarketCode());
        reportOrder.setClassCode(order.getClassCode());
        reportOrder.setBs(order.getBs());
        reportOrder.setHedgeFlag(order.getHedgeFlag());
        reportOrder.setOpenClose(order.getOpenClose());
        reportOrder.setCloseType(order.getCloseType());

        reportOrder.setSubmitTimeStr(order.getSubmitTimeStr());
        reportOrder.setTradeDateStr(LocalDate.now().toString());
        reportOrder.setEntrustTimeStr(LocalTime.now().toString());

        reportOrder.setOrder(order);

        reportOrder.setEntrustNo(ResourceManager.gv_entrustNo);//全局有效，每个柜台或是交易所保持唯一
        ResourceManager.gv_entrustNo -= 1;

        reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
        if (type == 1) {
            reportOrder.setMsgtype("OR");//不同type不同的编码
        } else if (type == 2) {
            reportOrder.setMsgtype("IR");//不同type不同的编码
        } else if (type == 3) {
            reportOrder.setMsgtype("PR");//不同type不同的编码
        } else {
            reportOrder.setMsgtype("ST");//不同type不同的编码
        }

        report.set("Title", "Report");
        report.set("PipID", 0);
        try {
            report.set("Data", reportOrder.EnCode(reportOrder));
            elvin.send(report);
        } catch (IOException ex) {
            log.error(ex);
        }

    }
    public static void CommitRejectReport(NewOrder order) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        //生成回报主体
        //order复制
        reportOrder.setOrderId(order.getOrderId());
        reportOrder.setWorkingQty(0);
        reportOrder.setUnWorkingQty(order.getOrderQty());
        reportOrder.setCancelQty(0);
        reportOrder.setPrice(order.getOrderPrice());
        reportOrder.setAccountCode(order.getAccountCode());
        reportOrder.setObj(order.getObj());
        reportOrder.setMarketCode(order.getMarketCode());
        reportOrder.setClassCode(order.getClassCode());
        reportOrder.setBs(order.getBs());
        reportOrder.setHedgeFlag(order.getHedgeFlag());
        reportOrder.setOpenClose(order.getOpenClose());
        reportOrder.setCloseType(order.getCloseType());

        reportOrder.setSubmitTimeStr(order.getSubmitTimeStr());
        reportOrder.setTradeDateStr(LocalDate.now().toString());
        reportOrder.setEntrustTimeStr(LocalTime.now().toString());

        reportOrder.setOrder(order);

        reportOrder.setEntrustNo(ResourceManager.gv_entrustNo);//全局有效，每个柜台或是交易所保持唯一
        ResourceManager.gv_entrustNo -= 1;

        reportOrder.setReportno(0);//1:正常，0：拒绝，非1非0错误代码
        String reportcontent = "当前不受理的委托";
        reportOrder.setReportcontent(reportcontent.getBytes());
        reportOrder.setMsgtype("OR");//不同type不同的编码

        report.set("Title", "Report");
        report.set("PipID", 0);
        try {
            report.set("Data", reportOrder.EnCode(reportOrder));
            elvin.send(report);
        } catch (IOException ex) {
            log.error(ex);
        }

    }
    public static void ExeCancelReport(NewOrder order,int qty) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        //生成回报主体
        //order复制
        reportOrder.setOrderId(order.getOrderId());
        reportOrder.setWorkingQty(0);
        reportOrder.setUnWorkingQty(0);
        reportOrder.setCancelQty(qty);
        reportOrder.setPrice(order.getOrderPrice());
        reportOrder.setAccountCode(order.getAccountCode());
        reportOrder.setObj(order.getObj());
        reportOrder.setMarketCode(order.getMarketCode());
        reportOrder.setClassCode(order.getClassCode());
        reportOrder.setBs(order.getBs());
        reportOrder.setHedgeFlag(order.getHedgeFlag());
        reportOrder.setOpenClose(order.getOpenClose());
        reportOrder.setCloseType(order.getCloseType());

        reportOrder.setSubmitTimeStr(order.getSubmitTimeStr());
        reportOrder.setTradeDateStr(LocalDate.now().toString());
        reportOrder.setEntrustTimeStr(LocalTime.now().toString());

        reportOrder.setOrder(order);

        reportOrder.setEntrustNo(ResourceManager.gv_entrustNo);//全局有效，每个柜台或是交易所保持唯一
        ResourceManager.gv_entrustNo -= 1;

        reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
        String reportcontent = "市场自动撤回";
        reportOrder.setReportcontent(reportcontent.getBytes());
        reportOrder.setMsgtype("CS");//不同type不同的编码

        report.set("Title", "Report");
        report.set("PipID", 0);
        try {
            report.set("Data", reportOrder.EnCode(reportOrder));
            elvin.send(report);
        } catch (IOException ex) {
            log.error(ex);
        }

    }
    public static void CommitReport(CancelOrder cancelOrder, int type) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        reportOrder.setOrderId(cancelOrder.getOrderId());
        if (!ResourceManager.Orderlist.containsKey(cancelOrder.getOrderId())) {
            reportOrder.setReportno(0);
            String str = "没有挂单数量，订单是否已经成交或是不存在的委托";
            reportOrder.setReportcontent(str.getBytes());
        } else {
            TradeSimOrderquene simOrder = ResourceManager.Orderlist.get(cancelOrder.getOrderId());
            String regionID = ResourceManager.getRegionID(simOrder.getMarketCode());
            if (!regionID.equals("C")) {
                if ((int) simOrder.getOrderQty() >= (int) cancelOrder.getCancelQty()) {
                    reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
                } else {
                    reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
                    reportOrder.setCancelQty(simOrder.getWorkingQty());
                }
            } else {
                reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
            }
        }
        if (type == 1) {
            reportOrder.setMsgtype("CR");//不同type不同的编码
        } else if (type == 2) {
            reportOrder.setMsgtype("IC");//不同type不同的编码
        }
        report.set("Title", "Report");
        report.set("PipID", 0);
        try {
            report.set("Data", reportOrder.EnCode(reportOrder));
            elvin.send(report);
        } catch (IOException ex) {
            log.error(ex);
        }
    }

    public static void CommitReport(AlterOrder alterOrder, int alterQty, int type) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        reportOrder.setOrderId(alterOrder.getOrderId());
        if (!ResourceManager.Orderlist.containsKey(alterOrder.getOrderId())) {
            reportOrder.setReportno(0);
            String str = "没有挂单数量，订单是否已经成交或是不存在的委托";
            reportOrder.setReportcontent(str.getBytes());
        } else {
            TradeSimOrderquene simOrder = ResourceManager.Orderlist.get(alterOrder.getOrderId());
            String regionID = ResourceManager.getRegionID(simOrder.getMarketCode());
            if (!regionID.equals("C")) {
                if ((int) simOrder.getOrderQty() >= (int) alterOrder.getAlterQty()) {
                    reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
                } else {
                    reportOrder.setReportno(0);//1:正常，0：拒绝，非1非0错误代码
                    String str = "改单数量非法";
                    reportOrder.setReportcontent(str.getBytes());
                }
            } else {
                reportOrder.setReportno(0);//1:正常，0：拒绝，非1非0错误代码
                String str = "大陆市场不支持改单功能";
                reportOrder.setReportcontent(str.getBytes());
            }
        }
        if (type == 1) {
            reportOrder.setMsgtype("AR");//不同type不同的编码
        } else if (type == 2) {
            reportOrder.setMsgtype("IA");//不同type不同的编码
        }
        report.set("Title", "Report");
        report.set("PipID", 0);
        try {
            report.set("Data", reportOrder.EnCode(reportOrder));
            elvin.send(report);
        } catch (IOException ex) {
            log.error(ex);
        }
    }
    /*
     1.成交执行回报
     MsgType：E1:成交回报，E2：撤单执行回报，E3：改价执行回报
     2.多态处理，接收3种委托
     */

    public static void ExecuteReport(NewOrder order, int excQty, float excPrice, int type) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        //生成回报主体
        //order复制
        reportOrder.setOrderId(order.getOrderId());
        int wq = order.getOrderQty() - excQty;
        reportOrder.setWorkingQty(wq);
        reportOrder.setUnWorkingQty(0);
        reportOrder.setCancelQty(0);
        reportOrder.setPrice(order.getOrderPrice());
        reportOrder.setAccountCode(order.getAccountCode());
        reportOrder.setObj(order.getObj());
        reportOrder.setMarketCode(order.getMarketCode());
        reportOrder.setClassCode(order.getClassCode());
        reportOrder.setBs(order.getBs());
        reportOrder.setHedgeFlag(order.getHedgeFlag());
        reportOrder.setOpenClose(order.getOpenClose());
        reportOrder.setCloseType(order.getCloseType());

        reportOrder.setSubmitTimeStr(order.getSubmitTimeStr());
        reportOrder.setTradeDateStr(LocalDate.now().toString());
        reportOrder.setExeTimeStr(LocalTime.now().toString());
        reportOrder.setExePrice(excPrice);
        reportOrder.setExeQty(excQty);
        reportOrder.setExeAmount(excPrice * excQty);
        reportOrder.setExeSequenceNo(ResourceManager.gv_exeSequenceNo);
        ResourceManager.gv_exeSequenceNo += 1;
        reportOrder.setExexseq(1);

        reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
        if (type == 1) {
            reportOrder.setMsgtype("OS");//不同type不同的编码
        } else if (type == 2) {
            reportOrder.setMsgtype("IS");//不同type不同的编码
        }

        report.set("Title", "Report");
        report.set("PipID", 0);
        try {
            report.set("Data", reportOrder.EnCode(reportOrder));
            elvin.send(report);
        } catch (IOException ex) {
            log.error(ex);
        }
    }

    public static void OtherExecuteReport(NewOrder order, int excQty, float excPrice, int type) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        //生成回报主体
        //order复制
        reportOrder.setOrderId(order.getOrderId());
        int wq = order.getOrderQty() - excQty;
        reportOrder.setWorkingQty(wq);
        reportOrder.setUnWorkingQty(0);
        reportOrder.setCancelQty(0);
        reportOrder.setPrice(order.getOrderPrice());
        reportOrder.setAccountCode(order.getAccountCode());
        reportOrder.setObj(order.getObj());
        reportOrder.setMarketCode(order.getMarketCode());
        reportOrder.setClassCode(order.getClassCode());
        reportOrder.setBs(order.getBs());
        reportOrder.setHedgeFlag(order.getHedgeFlag());
        reportOrder.setOpenClose(order.getOpenClose());
        reportOrder.setCloseType(order.getCloseType());

        reportOrder.setSubmitTimeStr(order.getSubmitTimeStr());
        reportOrder.setTradeDateStr(LocalDate.now().toString());
        reportOrder.setExeTimeStr(LocalTime.now().toString());
        reportOrder.setExePrice(excPrice);
        reportOrder.setExeQty(excQty);
        reportOrder.setExeAmount(excPrice * excQty);
        reportOrder.setExeSequenceNo(ResourceManager.gv_exeSequenceNo);
        ResourceManager.gv_exeSequenceNo += 1;
        reportOrder.setExexseq(1);

        reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
        if (type == 1) {
            reportOrder.setMsgtype("OS");//不同type不同的编码
        } else if (type == 2) {
            reportOrder.setMsgtype("IS");//不同type不同的编码
        }

        report.set("Title", "Report");
        report.set("PipID", 0);
        try {
            report.set("Data", reportOrder.EnCode(reportOrder));
            elvin.send(report);
        } catch (IOException ex) {
            log.error(ex);
        }
    }
//先报告后删除

    public static void ExecuteReport(CancelOrder cancelOrder, int cancelQty, int type) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        reportOrder.setOrderId(cancelOrder.getOrderId());
        if (ResourceManager.Orderlist.containsKey(cancelOrder.getOrderId())) {
            TradeSimOrderquene simOrder = ResourceManager.Orderlist.get(cancelOrder.getOrderId());
            String regionID = ResourceManager.getRegionID(simOrder.getMarketCode());
            log.debug("ID:"+cancelOrder.getOrderId()+" 市场："+regionID);
            if (!regionID.equals("C")) {
                log.debug("getWorkingQty:"+simOrder.getWorkingQty()+" getCancelQty："+cancelOrder.getCancelQty());
                if (simOrder.getWorkingQty() > cancelOrder.getCancelQty()) {
                    reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
                    reportOrder.setCancelQty(cancelQty);
                    simOrder.setCancelQty(cancelQty + simOrder.getCancelQty());
                    simOrder.setWorkingQty(simOrder.getWorkingQty() - cancelQty);
                    //数据库update
                    NewHibernateUtil.update(simOrder);

                } else {
                    reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
                    reportOrder.setCancelQty(simOrder.getWorkingQty());
                    //数据库删除
                    log.debug("是否执行了删除数据库");
                    NewHibernateUtil.delte(simOrder);
                    //撮合队列维护
                    ResourceManager.OrderQuenes.get(simOrder.getObj() + "_" + simOrder.getMarketCode()).remove(cancelOrder.getOrderId());
                    ResourceManager.Orderlist.remove(cancelOrder.getOrderId());
                    //ResourceManager.OrderQuenes.get("")

                }
            } else {
                reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
                reportOrder.setCancelQty(simOrder.getWorkingQty());
                //数据库删除
                NewHibernateUtil.delte(simOrder);
                //撮合队列维护
                ResourceManager.OrderQuenes.get(simOrder.getObj() + "_" + simOrder.getMarketCode()).remove(cancelOrder.getOrderId());
                ResourceManager.Orderlist.remove(cancelOrder.getOrderId());
            }
            if (type == 1) {
                reportOrder.setMsgtype("CS");//不同type不同的编码
            } else if (type == 2) {
                reportOrder.setMsgtype("IC");//不同type不同的编码
            }
            if (reportOrder.getReportno() == 1) {

                reportOrder.setOrderId(cancelOrder.getOrderId());

                report.set("Title", "Report");
                report.set("PipID", 0);
                try {
                    report.set("Data", reportOrder.EnCode(reportOrder));
                    elvin.send(report);
                } catch (IOException ex) {
                    log.error(ex);
                }
            }
        }
    }
//先通知后改数据

    public static void ExecuteReport(int orderID, int alterQty, float alterPrice, int type) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        if (ResourceManager.Orderlist.containsKey(orderID)) {
            TradeSimOrderquene simOrder = ResourceManager.Orderlist.get(orderID);
            String regionID = ResourceManager.getRegionID(simOrder.getMarketCode());
            if (!regionID.equals("C")) {
                if ((int) simOrder.getOrderQty() >= (int) alterQty) {
                    reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
                } else {
                    reportOrder.setReportno(0);//1:正常，0：拒绝，非1非0错误代码
                }
            } else {
                reportOrder.setReportno(0);//1:正常，0：拒绝，非1非0错误代码
                String str = "大陆市场不支持改单功能";
                reportOrder.setReportcontent(str.getBytes());
            }
            if (type == 1) {
                reportOrder.setMsgtype("AR");//不同type不同的编码
            } else if (type == 2) {
                reportOrder.setMsgtype("IA");//不同type不同的编码
            }
            if (reportOrder.getReportno() == 1) {
                reportOrder.setWorkingQty(alterQty);
                reportOrder.setPrice(alterPrice);

                report.set("Title", "Report");
                report.set("PipID", 0);
                try {
                    report.set("Data", reportOrder.EnCode(reportOrder));
                    elvin.send(report);
                } catch (IOException ex) {
                    log.error(ex);
                }
            }
        }
    }
//先改数据，再组织回报，最后动数据库

    public static void ExecuteReport(TradeSimOrderquene order, int excQty, float excPrice, int type, int exexseq) {
        Notification report = new Notification();
        ReportOrder reportOrder = new ReportOrder();
        //生成回报主体
        //order复制
        reportOrder.setOrderId(order.getOrderId());
//        int wq = order.getOrderQty() - excQty;
        reportOrder.setWorkingQty(order.getWorkingQty());
        reportOrder.setUnWorkingQty(order.getUnWorkingQty());
        reportOrder.setCancelQty(order.getCancelQty());
        reportOrder.setPrice(order.getOrderPrice());
        reportOrder.setAccountCode(order.getAccountCode());
        reportOrder.setObj(order.getObj());
        reportOrder.setMarketCode(order.getMarketCode());
        reportOrder.setClassCode(order.getClassCode());
        reportOrder.setBs(order.getBs());
        reportOrder.setHedgeFlag(order.getHedgeFlag());
        reportOrder.setOpenClose(order.getOpenClose());

        reportOrder.setTradeDateStr(LocalDate.now().toString());
        reportOrder.setExeTimeStr(LocalTime.now().toString());
        reportOrder.setExePrice(excPrice);
        reportOrder.setExeQty(excQty);
        reportOrder.setExeAmount(excPrice * excQty);
        reportOrder.setExeSequenceNo(ResourceManager.gv_exeSequenceNo);
        ResourceManager.gv_exeSequenceNo += 1;
        reportOrder.setExexseq(exexseq);

        reportOrder.setReportno(1);//1:正常，0：拒绝，非1非0错误代码
        if (type == 1) {
            reportOrder.setMsgtype("OS");//不同type不同的编码
        } else if (type == 2) {
            reportOrder.setMsgtype("IS");//不同type不同的编码
        }

        report.set("Title", "Report");
        report.set("PipID", 0);
        try {
            report.set("Data", reportOrder.EnCode(reportOrder));
            elvin.send(report);
        } catch (IOException ex) {
            log.error(ex);
        }
    }
}
